package com.zjw.study.thread03_synchronized;

/**
 * 线程同步
 * 
 * 面试题：
 * 子线程循环10次，主线程循环100。如此循环50次
 * @author Administrator
 *
 */
public class ThreadSynchronized {
	/**
	 * 是否轮到主线程执行
	 */
	private boolean executeMain = false;
	
	public static void main(String[] args) {
		ThreadSynchronized ts = new ThreadSynchronized();
		ts.sync01();
	}
	
	/**
	 * 线程通信示范
	 */
	void sync01() {
		//子线程
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 1; i <= 50; i++) {
					outChild(i);
				}
			}
		}).start();
		
		//主线程，即main
		for (int i = 1; i <= 50; i++) {
			outMain(i);
		}
	}
	
	/**
	 * 主线程输出
	 * 主线程：即执行main方法的线程
	 * @param i
	 */
	private synchronized void outMain(int i) {
		//如果为false，应子线程执行，主线程等待
		//虽然可以用if，但由于线程有时会未通知时唤醒（概率很低，详见源码注释），最好用while
		while(!executeMain) {
			threadWait();
		}
		for (int j = 1; j <= 100; j++) {
			System.out.println("main i=" + i + "，j=" + j);
		}
		executeMain = !executeMain;
		this.notify();//通知线程执行处理
	}
	/**
	 * 子线程输出
	 * 子线程：在main线程中新建的线程
	 * @param i
	 */
	private synchronized void outChild(int i) {
		//如果为true，应主线程执行，子线程等待
		while(executeMain) {
			threadWait();
		}
		for (int j = 1; j <= 10; j++) {
			System.out.println("child i=" + i + "，j=" + j);
		}
		executeMain = !executeMain;
		this.notify();//通知线程执行处理
	}
	
	/**
	 * 线程等待
	 */
	private void threadWait() {
		try {
			this.wait();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}
